#include "background.h"

#include <mythtv/oldsettings.h>
#include <mythtv/mythcontext.h>
#include <qimage.h>
#include <qdir.h>
#include <qregexp.h>
#include <sstream>
#include "SimpleIni.h"
#include "unzip.h"

#include "CDGWidgetGL.h"

const int bkgDimTime = 10; //sec
const float bkgSpeed = (1.0f/800);

void background::create(void)
{
    m_position=0.0f;
    m_rightDirection=false;
    m_dim=0;
    m_dim=(animTimer*bkgDimTime);

    QString setting = gContext->GetSetting("CdgBackgroundPath");
    cerr << "Bkg: Backgroundpath: " << setting << endl;
    QDir imageDir(setting);
    if (imageDir.isReadable())
    {
        //Find all backgrounds
        const QFileInfoList* List = imageDir.entryInfoList();
        QFileInfoList result;
        QString image;
        for (QFileInfoListIterator it(*List); it; ++it)
        {   
            QFileInfo* file = it.current();
            QString filename = file->fileName();
            
            if (filename == "." || filename == "..")
            {   
                continue;
            }
            if (!file->isDir() && ((file->extension(false) == "jpg") || (file->extension(false) == "kfp")))
            {
               result.append(file);
            }
        }

        //Use one of the found background
        srand((unsigned)time(0)); 
        if(result.count() > 0)
        { 
            int imagepos = rand()%result.count(); 
            cerr << "Got " << imagepos << " of " << result.count() << endl;

            //Check which type of background
            if(result.at(imagepos)->extension(false) == "kfp")
            {
                m_animType = SINGLE;
                LoadImageFromKFP(result.at(imagepos)->absFilePath(),0);
                return;
            }
//             else if(1)
//             {
//                 m_animType = BOUNCE;
//                 LoadImage(imageDir.absPath()+"/panorama1.jpg",0);
//                 LoadImage(imageDir.absPath()+"/panorama2.jpg",1);
//                 return;
//             }
            else
            {
                m_animType = SINGLE;
                LoadImage(result.at(imagepos)->absFilePath(),0);
                return;
            }
        }
    }

    //Default background
    cerr << "Bkg: Loading backgroundimage from theme" << endl;
    m_animType = SINGLE;
    Settings *tmp = gContext->qtconfig();
    QString backgroundname = tmp->GetSetting("BackgroundPixmap");
    backgroundname = gContext->GetThemeDir() + backgroundname;
    LoadImage(backgroundname,0);
}

void background::clear()
{
    if (m_texture[0])
       glDeleteTextures(1, &m_texture[0]);
    
    if (m_texture[1])
       glDeleteTextures(1, &m_texture[1]);
}


void background::paintGL(void)
{
    //Background 1
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    if(m_animType==BOUNCE)
    {
        //ScrollBounce right-left
        if(m_rightDirection) {
            m_position += bkgSpeed;
            if(m_position>2.0f)
            {
                m_position -= bkgSpeed;
                m_rightDirection = false;
            }
        } else {
            m_position -= bkgSpeed;
            if(m_position<0.0f)
            {
                m_position += bkgSpeed;
                m_rightDirection = true;
            }
        }
        //glTranslatef(-2.0f+m_position+0.5f/m_GLSize, 0.0f, 0.0f);
        glTranslatef(-2.0f+m_position, 0.0f, 0.0f);
    }

    //Bind texture
    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();
    glBindTexture(GL_TEXTURE_2D, m_texture[0]);

    glBegin(GL_QUADS);
    {
        glColor4f(1.0f, 1.0f, 1.0f, m_dim*1.0f/(animTimer*bkgDimTime));
        glTexCoord2f(0.5f/m_GLSize,             0.5f/m_GLSize);             glVertex3f(-1.0f, -1.0f, 0.0f);
        glTexCoord2f((m_GLSize-0.5f)/m_GLSize, 0.5f/m_GLSize);             glVertex3f(+1.0f, -1.0f, 0.0f);
        glTexCoord2f((m_GLSize-0.5f)/m_GLSize, (m_GLSize-0.5f)/m_GLSize); glVertex3f(+1.0f, +1.0f, 0.0f);
        glTexCoord2f(0.5f/m_GLSize,             (m_GLSize-0.5f)/m_GLSize); glVertex3f(-1.0f, +1.0f, 0.0f);
    }
    glEnd();

    if(m_animType==BOUNCE)
    {
        //Background 2
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glTranslatef(m_position, 0.0f, 0.0f);

        //Bind texture
        glMatrixMode(GL_TEXTURE);
        glLoadIdentity();
        glBindTexture(GL_TEXTURE_2D, m_texture[1]);

        glBegin(GL_QUADS);
        {
            glColor4f(1.0f, 1.0f, 1.0f, m_dim*1.0f/(animTimer*bkgDimTime));
            glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f);
            glTexCoord2f(1.0f, 0.0f); glVertex3f(+1.0f, -1.0f, 0.0f);
            glTexCoord2f(1.0f, 1.0f); glVertex3f(+1.0f, +1.0f, 0.0f);
            glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, +1.0f, 0.0f);
        }
        glEnd();

        // Update background dim-in effect
        if(m_dim<(animTimer*bkgDimTime))
           m_dim++;
    }
}


void background::LoadImage(QString loadFile, int order)
{
    cerr << "Bkg: LoadImage (GL:" << order << ") File:" << loadFile << endl;

    QImage image;
    image.load(loadFile);
    if (image.isNull())
    {
        image = QImage( 300, 216, 32 );
        image.fill(Qt::black.rgb() );
        image.fill(QColor(0,0,0).rgb());// Qt::green.rgb() );
    }

    QSize m_texSize = QSize(CDGWidgetGL::GetNearestGLTextureSize(image.width()),
                            CDGWidgetGL::GetNearestGLTextureSize(image.height()));
    cerr << "W: " << image.width() << "->" <<  m_texSize.width() << 
        " H: " << image.height() << "->" << m_texSize.height() << endl;

    m_GLSize = (float)m_texSize.width();

    QImage glImage = QGLWidget::convertToGLFormat(image.smoothScale(m_texSize));
     
    glGenTextures(1, &m_texture[order]);
    glBindTexture(GL_TEXTURE_2D, m_texture[order]);

    /* actually generate the texture */
    glTexImage2D(GL_TEXTURE_2D, 0, 3, glImage.width(), glImage.height(), 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, glImage.bits());

    /* enable linear filtering  */
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}


void background::LoadImageFromKFP(QString loadFile, int order)
{
    cerr << "Bkg: LoadImageFromKFP (GL:" << order << ") File:" << loadFile << endl;

    char filename_inzip[256];
    unz_file_info file_info;    
    int err;
    unzFile zf;

    if ((zf = unzOpen(loadFile)))
    {
        if (unzLocateFile(zf,"Song.ini",0) == UNZ_OK)
        {
            if (unzOpenCurrentFile(zf) == UNZ_OK)
            {
                err = unzGetCurrentFileInfo(zf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
                cerr << "Found file: " << filename_inzip << " Err:" << err << endl;

                CSimpleIniCaseA ini;
                ini.SetUnicode(true);
                ini.SetMultiKey(true);
                ini.SetMultiLine(true);

                QByteArray buffer(file_info.uncompressed_size);
                unsigned int count = unzReadCurrentFile(zf, buffer.data(), file_info.uncompressed_size);
                if(count==file_info.uncompressed_size)
                {
                    ini.Load(buffer.data(), file_info.uncompressed_size);
                    
                }   
                unzCloseCurrentFile(zf);
                
                cerr << std::string(buffer.data(), file_info.uncompressed_size) << endl;
                std::string image = ini.GetValue("Eff1","LibImage");
                if(image.length() == 0)
                {
                    std::string animStr = ini.GetValue("Eff1","NbAnim"); //Animation
                    int anim = atoi(animStr.c_str());

                    for(int i=0;i<anim;++i)
                    {
                        std::stringstream sstr;
                        sstr << "Anim" << i;
                        QString line = ini.GetValue("Eff1",sstr.str().c_str()); //Animation

                        QStringList elements( QStringList::split( "|", line ) );

                        cerr << "======"<<elements.count()<<" LINE: " << line << endl;
                        for ( QStringList::Iterator it = elements.begin(); it != elements.end(); ++it ) {
                            cerr << "============TYPE: " << *it << endl;
                            
                            QStringList type( QStringList::split(":", *it));
                            if((type.count() == 2))
                            {
                                if(type[0]=="ChgBgImg")
                                {
                                    cerr << "Handling type: " << type[0] << endl;
                                    cerr << "Elements: " << type[1] << endl;

                                    QStringList pairs( QStringList::split(",", type[1]) );
                                    for ( QStringList::Iterator p_it = pairs.begin(); p_it != pairs.end(); ++p_it ) {
                                        QStringList pair( QStringList::split("=", *p_it));
                                        if((pair.count() == 2) && (pair[0]=="LibImage"))
                                           image = std::string(pair[1].data());
                                        else
                                           cerr << "Unhandled element: " << pair[0] << " = " << pair[1] << endl;
                                    }
                                }
                                else 
                                {
                                    cerr << "Unhandled type: " << type[0] << endl;
                                }
                            }
                            else 
                            {
                                cerr << "No elements" << endl;
                            }                            
                        }
                        
                        //Anim0=0|ChgBgImg:LibImage=Musette1.jpg,Effect=ZoomOutFade,TransitionTime=7
//                         QRegExp rx;
//                         rx.setPattern( "^([\\d]+)\\|([^\\s]+):([^\\s]+),([^\t]+).*" );
//                         if ( rx.search( info ) != -1 ) {
//                             cerr << rx.cap( 1 ) <<"  "<< rx.cap( 2 ) <<"  "<< rx.cap( 3 ) <<"  "<< rx.cap( 4 ) << endl;
//                             //PRINTS
//                             //0  ChgBgImg  LibImage=wallpaper-70s.jpg,Effect=MoveBottom  TransitionTime=2

//                             LibImage = rx.cap( 4 );
//                         }
                        
                    }
                }


                cerr << "Locate: " << image << endl;
                if (unzLocateFile(zf,image.c_str(),0) == UNZ_OK)
                {
                    if (unzOpenCurrentFile(zf) == UNZ_OK)
                    {
                        err = unzGetCurrentFileInfo(zf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
                        cerr << "Found file: " << filename_inzip << " Size: " << file_info.uncompressed_size <<
                            " Err:" << err << endl;
                        
                        QByteArray buffer(file_info.uncompressed_size);
                        count = unzReadCurrentFile(zf, buffer.data(), file_info.uncompressed_size);
                        if(count==file_info.uncompressed_size)
                        {
                            QImage image;
                            image.loadFromData(buffer);
                            
                            QSize m_texSize = QSize(CDGWidgetGL::GetNearestGLTextureSize(image.width()),
                                                    CDGWidgetGL::GetNearestGLTextureSize(image.height()));
                            cerr << "W: " << image.width() << "->" <<  m_texSize.width() << 
                                " H: " << image.height() << "->" << m_texSize.height() << endl;
                            
                            m_GLSize = (float)m_texSize.width();
                            
                            QImage glImage = QGLWidget::convertToGLFormat(image.smoothScale(m_texSize));
                            
                            glGenTextures(1, &m_texture[order]);
                            glBindTexture(GL_TEXTURE_2D, m_texture[order]);
                            
                            /* actually generate the texture */
                            glTexImage2D(GL_TEXTURE_2D, 0, 3, glImage.width(), glImage.height(), 0,
                                         GL_RGBA, GL_UNSIGNED_BYTE, glImage.bits());
                            
                            /* enable linear filtering  */
                            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
                            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                        }
                        unzCloseCurrentFile(zf);
                    }
                    else 
                    {
                        cerr << "Cant open file:" << image << endl;
                    }
                }
                else 
                {
                    cerr << "Cant find file:" << image << endl;
                }
            }
        }
        else 
        {
            cerr << "Cant find INI-file" << endl;
        }
        unzClose(zf);
    }
}




// [Materials]
// MatCount=2
// Mat0=Musette1 mini.jpg
// Mat1=Musette1.jpg
// [Eff1]
// ID=51
// InPractice=1
// Color=#000000
// LibImage=
// ImageColor=#FFFFFF
// NbAnim=1
// Anim0=0|ChgBgImg:LibImage=Musette1.jpg,Effect=ZoomOutFade,TransitionTime=7

// [Materials]
// MatCount=3
// Mat0=panorama1.jpg
// Mat1=panorama2.jpg
// Mat2=summer-m.jpg
